import copy
import json
from common.utils import common_type_merge_step
from common.read_xmind import string_io
from common.test_data import TestData

test_data = TestData()


class CommonOperation:

    @staticmethod
    def new_step(model_data, step, value):
        """
        生成用例步骤
        :param model_data: 模块数据
        :param step:具体某一步骤
        :param value: 值
        :return:
        """
        new_step = []
        # TODO 循环步骤
        for i in model_data['步骤']:
            if i in model_data['data_step'] and i == step:
                new_step.append('{}:{}'.format(step, value))
            else:
                new_step.append(i)
        return new_step

    def step_common(self, model_data, step, value, result, type_case, case_title):
        """
        生成用例公共方法
        :param model_data: 模型数据
        :param step:具体某一步骤
        :param value: 值
        :param result: 结果
        :param type_case: {"true": [], "false": [], "step": []}
        :param case_title: 用例标题
        :return:
        """
        template_data = copy.deepcopy(model_data)
        # TODO 主要为了获取某个操作类型下完整的步骤，如： ["输入任务名称","输入检测目标","选择1:3","选择2:6","点击确定"]
        # TODO  若不加步骤会是  ["输入任务名称","输入检测目标","选择1","选择2:6","点击确定"]
        if result == '成功':
            type_case['full_step'][model_data['步骤'].index(step)] = '{}:{}'.format(step, value)
        # TODO 生成用例
        template_data['用例标题'] = case_title
        template_data['步骤'] = self.new_step(model_data, step, value)
        template_data['结果'] = template_data['结果'][result]
        del template_data['operation_data']
        del template_data['data_step']
        if result == '失败':
            template_data['用例等级'] = 'P2'
            type_case['false'].append(template_data)
        else:
            template_data['用例等级'] = 'P1'
            type_case['true'].append(template_data)

    @staticmethod
    def get_data(operate_type):
        """
        拿到xmind数据重新组装格式
        :param operate_type: 操作类型
        :return:
        """
        result = []
        for model in json.loads(string_io.getvalue()):
            model['operation_data'] = {}
            model['data_step'] = []
            try:
                # TODO 处理查询里没有步骤的错误 以及 步骤中没有操作类型的错误
                for key, value in model['步骤']['data'].items():
                    try:
                        if value['操作类型'] == operate_type:
                            model['operation_data'][key] = value
                            model['data_step'].append(key)
                    except KeyError:
                        pass
                model['步骤'] = model['步骤']['step']
                result.append(model)
            except:
                pass
        return result

    def operation_type(self, operate_type, generate_case):
        """
        生成某个操作类型的case
        :param operate_type:
        :param generate_case:
        :return:
        """
        result = []
        for model in self.get_data(operate_type):
            case_data = {"true": [], "false": [], "step": model['步骤'], 'full_step': copy.deepcopy(model['步骤'])}
            # TODO 循环模块
            for i in model['data_step']:
                # 循环处理每一步输入的数据
                generate_case(model, i, model['operation_data'][i], case_data)
            # TODO 合并步骤
            common_type_merge_step(model, case_data)
            result.append(case_data)
        return result

    @staticmethod
    def case_tip(model_data, data: dict, result):
        """
        逆向用例拼接标题，若对应需求有声明错误的提示，就采用作为标题，反之直接用失败的
        :param model_data:
        :param data:
        :param result:
        :return:
        """
        if result == '失败':
            if data['err_tip']:
                return data['err_tip']
            return model_data['结果']['失败']
        else:
            return model_data['结果']['成功']

    def required(self, require, model_data, data_step, value, type_case):
        """
        处理必填的用例
        :param require: select_data['必填']
        :param model_data: 模型数据
        :param data_step: 步骤数据
        :param value: 值
        :param type_case: {"true": [], "false": [], "step": []}
        :return:
        """
        """不传“必填”字段，不生成相关用例"""
        if '必填' in require.keys():
            # TODO 是否必填
            if require['必填']['value'] == '是':
                case_title = "{},不{}，{}".format(model_data['用例标题'], data_step,
                                                self.case_tip(model_data, require['必填'], '失败'))
                self.step_common(model_data, data_step, value, '失败', type_case, case_title)
            else:
                case_title = "{},不{}，{}".format(model_data['用例标题'], data_step,
                                                self.case_tip(model_data, require['必填'], '成功'))
                self.step_common(model_data, data_step, value, '成功', type_case, case_title)
